← Back

Armold — 5-DOF Robotic Arm

Overview

Armold is a 5-DOF robotic arm built with help from Sweep Dynamics, whose mechanical design it's based on. I built it around a completely different electronics and control stack — new motors, a CAN bus architecture, a custom ros2_control hardware interface, and modified printed parts to fit it all. The goal was a platform that runs a real motion-planning stack end to end: Cartesian goal poses down through inverse kinematics to closed-loop motors on a CAN bus.

Armold 5-DOF Robot Arm

Hardware

The joints are driven by MKS Servo42D closed-loop steppers in SR_vFOC mode, each on its own CAN ID (01–05). Output reduction comes from 1:26 cycloidal drives designed by Sweep Dynamics — high ratio in a compact envelope, low backlash, and enough torque density to hold the arm's weight without sagging between planning cycles. Backlash matters more than it seems: every degree of slop at a joint compounds through the kinematic chain into end-effector error, degrading how well the computed IK solution matches reality.

Integrating the reducers wasn't drop-in — I modified the provided models to match my motor mounts, shaft interface, and printer tolerances. Two lessons from that:

The gripper is a hobby PWM servo driven by an ESP32 over LEDC, on its own 5–6 V supply, kept separate from the CAN side.

Armold joint and cycloidal drive detail Armold electronics and CAN wiring CAD assembly view of Armold's joint stack

Kinematics

Armold is a 5-DOF serial chain — base yaw, shoulder pitch, elbow pitch, wrist pitch, and wrist roll — terminating in a fixed tool0 frame at the gripper mount, described in a URDF with each joint's axis and origin pulled from CAD.

Forward kinematics chains the joint transforms into a tool pose; inverse kinematics solves the useful direction — given a desired pose, what joint angles reach it — which is what makes the arm commandable in task space instead of joint space. MoveIt 2 solves this numerically from the URDF via KDL. A few implications worth knowing:

Electronics and CAN

A Raspberry Pi 4 runs the stack, talking to the motor bus through an MKS CANable V2.0 Pro USB-CAN adapter, bridged into ROS 2 with ros2_socketcan on can0 at 500 kbit/s. The bus is a daisy chain of CANH/CANL with 120 Ω termination at both ends, motor power on a separate parallel rail.

Things that cost me time:

Software

ROS 2 Jazzy with MoveIt 2 and ros2_control, split across three packages:

Development happens on a Windows 11 laptop through WSL2 (Ubuntu 24.04); the Pi runs headless over SSH as the deployment target, with CycloneDDS handling middleware across the two. I got the full pipeline running against mock hardware first — move_group, controller_manager, joint_state_broadcaster, arm_controller, and /joint_states all healthy — before swapping in real motors, so hardware bugs stayed isolated from planning/IK bugs.

Debugging Notes Worth Writing Down

The failures that ate the most hours were almost all configuration, not code:

Where It's Going

Next up is finishing the real CAN command implementation in the hardware interface's read()/write() bodies, then adding a camera. Longer term, the goal is using Armold as a platform for LeRobot/VLA experimentation, with the ros2_control hardware interface bridging learned policies to the motors.

One constraint already run into: the Servo42D closed-loop steppers aren't backdrivable, so kinesthetic teaching isn't practical with this hardware — any demonstration pipeline will have to come from teleoperation instead.